mod selection;

use std::any::{Any, TypeId};

pub use selection::*;

use crate::math::{measure::Measure, Rect};

pub trait View: Any {
    fn rect(&self) -> &Rect;
    fn measure(&self) -> &Measure;

    fn as_view_group(&self) -> Option<&dyn ViewGroup>;
}

impl dyn View {
    pub fn is<V: View>(&self) -> bool {
        self.type_id() == TypeId::of::<V>()
    }

    pub fn cast<V: View>(&self) -> Option<&V> {
        if self.is::<V>() {
            Some(unsafe { &*(self as *const dyn View as *const V) })
        } else {
            None
        }
    }

    pub fn cast_mut<V: View>(&mut self) -> Option<&mut V> {
        if self.is::<V>() {
            Some(unsafe { &mut *(self as *mut dyn View as *mut V) })
        } else {
            None
        }
    }
}

pub trait ViewGroup: View {
    fn children(&self) -> &[Box<dyn View>];
}
